package com.icloud.system.boot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.icloud.common.cache.service.RedisService;
import com.icloud.common.database.enums.TFEnum;
import com.icloud.common.database.mapper.*;
import com.icloud.common.database.model.*;
import com.icloud.common.web.util.AuthUtil;
import com.icloud.common.web.vo.PageVO;
import com.icloud.system.boot.dto.AdminCustomerPageDto;
import com.icloud.system.boot.mapper.AppWhiteListOperationLogMapper;
import com.icloud.system.boot.mapper.CustomerInviteMapper;
import com.icloud.common.database.mapper.CustomerSettingsMapper;
import com.icloud.system.boot.model.AppWhiteListOperationLog;
import com.icloud.system.boot.model.CustomerInvite;
import com.icloud.common.database.model.CustomerSettings;
import com.icloud.system.boot.service.AdminCustomerService;
import com.icloud.system.boot.vo.AdminCustomerVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AdminCustomerServiceImpl extends ServiceImpl<AppCustomerMapper, AppCustomer> implements AdminCustomerService {
    @Autowired
    private AppCustomerAuthMapper appCustomerAuthMapper;
    @Autowired
    private CustomerWalletMapper customerWalletMapper;
    @Autowired
    private CustomerInviteMapper customerInviteMapper;
    @Autowired
    private CustomerSettingsMapper customerSettingsMapper;
    @Autowired
    private AppWhiteListOperationLogMapper appWhiteListOperationLogMapper;
    @Autowired
    private AttentionMapper attentionMapper;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RedisService redisService;
    @Autowired
    private AuthUtil authUtil;

    @Override
    public PageVO<AdminCustomerVo> customerPage(AdminCustomerPageDto dto) {
        Long loginId = authUtil.getUserId();
        String nickname = dto.getNickname();
        String isMember = dto.getIsMember();

        String silence = dto.getSilence();
        TFEnum silenceTFEnum = TFEnum.byCode(silence);

        IPage page = Page.of(dto.getCurrent(), dto.getPageSize());
        List<Long> custIdList = null;
        Map<Long, CustomerSettings> csMap = new HashMap<>();
        if(silenceTFEnum!=null){
            LambdaQueryWrapper<CustomerSettings> custSetQuery = new LambdaQueryWrapper<>();
            custSetQuery.eq(CustomerSettings::getSilence, silence);
            custSetQuery.orderByDesc(CustomerSettings::getUpdatedAt);
            IPage<CustomerSettings> custSetPage = customerSettingsMapper.selectPage(page, custSetQuery);
            List<CustomerSettings> custSetList = custSetPage.getRecords();
            custIdList = custSetList.stream().map(CustomerSettings::getCustomerId).collect(Collectors.toList());
            Map<Long, CustomerSettings> csTmpMap = custSetList.stream().collect(Collectors.toMap(CustomerSettings::getCustomerId, Function.identity()));
            if(!csTmpMap.isEmpty()) {
                csMap.putAll(csTmpMap);
            }
        }
        List<AppCustomer> custList = null;
        LambdaQueryWrapper<AppCustomer> custQuery = new LambdaQueryWrapper<>();
        custQuery.like(StringUtils.isNotBlank(nickname), AppCustomer::getNickname, nickname);
        custQuery.orderByDesc(AppCustomer::getUpdatedAt);
        if(!CollectionUtils.isEmpty(custIdList)) {
            custQuery.eq(AppCustomer::getId, custIdList);
            custList = baseMapper.selectList(custQuery);
        }else{
            IPage<AppCustomer> customerPage = baseMapper.selectPage(page, custQuery);
            custList = customerPage.getRecords();
        }
        custIdList = custList.stream().map(AppCustomer::getId).collect(Collectors.toList());
        LambdaQueryWrapper<CustomerWallet> cwQuery = new LambdaQueryWrapper<>();
        cwQuery.in(CustomerWallet::getCustomerId, custIdList);
        List<CustomerWallet> cwList = customerWalletMapper.selectList(cwQuery);
        Map<Long, CustomerWallet> cwMap = cwList.stream().collect(Collectors.toMap(CustomerWallet::getCustomerId, Function.identity()));

        // 推荐人
        LambdaQueryWrapper<CustomerInvite> ciQuery = new LambdaQueryWrapper<>();
        ciQuery.in(CustomerInvite::getInviteeId, custIdList);
        List<CustomerInvite> ciList = customerInviteMapper.selectList(ciQuery);
        Set<Long> inviterIdSet = ciList.stream().map(CustomerInvite::getInviterId).collect(Collectors.toSet());
        LambdaQueryWrapper<AppCustomer> inviterQuery = new LambdaQueryWrapper<>();
        inviterQuery.in(AppCustomer::getId, inviterIdSet);
        List<AppCustomer> inviterList = baseMapper.selectList(inviterQuery);
        Map<Long, String> inviterMap = inviterList.stream().collect(Collectors.toMap(AppCustomer::getId, AppCustomer::getNickname));
        Map<Long, String> ciNicknameMap = ciList.stream().collect(Collectors.toMap(CustomerInvite::getInviteeId, v->inviterMap.get(v.getInviterId())));

        // 邀请人数
        LambdaQueryWrapper<CustomerInvite> ciNumQuery = new LambdaQueryWrapper<>();
        ciNumQuery.in(CustomerInvite::getInviterId, custIdList);
        List<CustomerInvite> ciNumList = customerInviteMapper.selectList(ciNumQuery);
        Map<Long, Long> ciNumMap = ciNumList.stream().collect(Collectors.groupingBy(CustomerInvite::getInviterId, Collectors.counting()));

        List<AppWhiteListOperationLog> loginloglist = appWhiteListOperationLogMapper.findMaxMinLoginLog(custIdList);
        Map<Long, List<AppWhiteListOperationLog>> loginMap = loginloglist.stream().collect(Collectors.groupingBy(AppWhiteListOperationLog::getCustomerId));

        List<AdminCustomerVo> voList = custList.stream().map(cust->{
            Long custId = cust.getId();
            String custNickname = cust.getNickname();
            CustomerWallet cw = cwMap.get(custId);
            String inviterNickname = ciNicknameMap.get(custId);
            CustomerSettings cs = csMap.get(custId);
            List<AppWhiteListOperationLog> loginList = loginMap.get(custId);
            Long inviterNumber = ciNumMap.get(custId);

            AdminCustomerVo vo = new AdminCustomerVo();
            vo.setCustomerId(custId);
            vo.setNickname(custNickname);
            vo.setInviterNickname(inviterNickname);
            vo.setInviteeNumber(inviterNumber);
            if(cw!=null){
                vo.setPlatformBal(cw.getBcpc());
            }
            if(cs!=null){
                vo.setSilence(cs.getSilence());
            }
            if(!CollectionUtils.isEmpty(loginList)){
                AppWhiteListOperationLog maxCreateTimeJournal = loginList.get(0);
                vo.setLastLoginTime(maxCreateTimeJournal.getCreatedAt());
                if(loginList.size()>1) {
                    AppWhiteListOperationLog minCreateTimeJournal = loginList.get(1);
                    vo.setFirstLoginTime(minCreateTimeJournal.getCreatedAt());
                }
            }

            return vo;
        }).collect(Collectors.toList());

        PageVO<AdminCustomerVo> pageVO = new PageVO<>();
        pageVO.setList(voList);
        pageVO.setTotal(page.getTotal());
        return pageVO;
    }
}
